home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
gnu
/
nethack.lha
/
nethack-3.1
/
src
/
cmd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-22
|
27KB
|
1,142 lines
/* SCCS Id: @(#)cmd.c 3.1 92/11/25 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
#include "hack.h"
#include "func_tab.h"
/*
* Some systems may have getchar() return EOF for various reasons, and
* we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
*/
#if defined(SYSV) || defined(DGUX) || defined(HPUX)
#define NR_OF_EOFS 20
#endif
#ifdef DUMB /* stuff commented out in extern.h, but needed here */
extern int NDECL(doapply); /**/
extern int NDECL(dorub); /**/
extern int NDECL(dojump); /**/
extern int NDECL(doextlist); /**/
extern int NDECL(dodrop); /**/
extern int NDECL(doddrop); /**/
extern int NDECL(dodown); /**/
extern int NDECL(doup); /**/
extern int NDECL(donull); /**/
extern int NDECL(dowipe); /**/
extern int NDECL(do_mname); /**/
extern int NDECL(ddocall); /**/
extern int NDECL(dotakeoff); /**/
extern int NDECL(doremring); /**/
extern int NDECL(dowear); /**/
extern int NDECL(doputon); /**/
extern int NDECL(doddoremarm); /**/
extern int NDECL(dokick); /**/
extern int NDECL(dothrow); /**/
extern int NDECL(doeat); /**/
extern int NDECL(done2); /**/
extern int NDECL(doengrave); /**/
extern int NDECL(dopickup); /**/
extern int NDECL(ddoinv); /**/
extern int NDECL(dotypeinv); /**/
extern int NDECL(dolook); /**/
extern int NDECL(doprgold); /**/
extern int NDECL(doprwep); /**/
extern int NDECL(doprarm); /**/
extern int NDECL(doprring); /**/
extern int NDECL(dopramulet); /**/
extern int NDECL(doprtool); /**/
extern int NDECL(dosuspend); /**/
extern int NDECL(doforce); /**/
extern int NDECL(doopen); /**/
extern int NDECL(doclose); /**/
extern int NDECL(dosh); /**/
extern int NDECL(dodiscovered); /**/
extern int NDECL(doset); /**/
extern int NDECL(dotogglepickup); /**/
extern int NDECL(dowhatis); /**/
extern int NDECL(doquickwhatis); /**/
extern int NDECL(dowhatdoes); /**/
extern int NDECL(dohelp); /**/
extern int NDECL(dohistory); /**/
extern int NDECL(doloot); /**/
extern int NDECL(dodrink); /**/
extern int NDECL(dodip); /**/
extern int NDECL(dosacrifice); /**/
extern int NDECL(dopray); /**/
extern int NDECL(doturn); /**/
extern int NDECL(doredraw); /**/
extern int NDECL(doread); /**/
extern int NDECL(dosave); /**/
extern int NDECL(dosearch); /**/
extern int NDECL(doidtrap); /**/
extern int NDECL(dopay); /**/
extern int NDECL(dosit); /**/
extern int NDECL(dotalk); /**/
extern int NDECL(docast); /**/
extern int NDECL(dovspell); /**/
extern int NDECL(dotele); /**/
extern int NDECL(dountrap); /**/
extern int NDECL(doversion); /**/
extern int NDECL(doextversion); /**/
extern int NDECL(dowield); /**/
extern int NDECL(dozap); /**/
extern int NDECL(doorganize); /**/
#endif /* DUMB */
#ifdef OVL1
static int NDECL((*timed_occ_fn));
#endif /* OVL1 */
STATIC_PTR int NDECL(doprev_message);
STATIC_PTR int NDECL(timed_occupation);
STATIC_PTR int NDECL(doextcmd);
# ifdef POLYSELF
STATIC_PTR int NDECL(domonability);
# endif
# ifdef WIZARD
STATIC_PTR int NDECL(wiz_wish);
STATIC_PTR int NDECL(wiz_identify);
STATIC_PTR int NDECL(wiz_map);
STATIC_PTR int NDECL(wiz_genesis);
STATIC_PTR int NDECL(wiz_where);
STATIC_PTR int NDECL(wiz_detect);
STATIC_PTR int NDECL(wiz_level_tele);
# endif
# ifdef EXPLORE_MODE
STATIC_PTR int NDECL(enter_explore_mode);
# endif
# if defined(WIZARD) || defined(EXPLORE_MODE)
STATIC_PTR int NDECL(wiz_attributes);
# endif
#ifdef OVLB
static void FDECL(enlght_line, (const char *,const char *,const char *));
#ifdef UNIX
static void NDECL(end_of_input);
#endif
#endif /* OVLB */
#ifdef OVL0
static int FDECL(click_to_cmd, (int,int,int));
#endif /* OVL0 */
STATIC_OVL char *NDECL(parse);
#ifdef UNIX
extern boolean hu;
#endif
#ifdef OVL1
STATIC_PTR int
doprev_message()
{
return nh_doprev_message();
}
/* Count down by decrementing multi */
STATIC_PTR int
timed_occupation() {
(*timed_occ_fn)();
if (multi > 0)
multi--;
return multi > 0;
}
/* If you have moved since initially setting some occupations, they
* now shouldn't be able to restart.
*
* The basic rule is that if you are carrying it, you can continue
* since it is with you. If you are acting on something at a distance,
* your orientation to it must have changed when you moved.
*
* The exception to this is taking off items, since they can be taken
* off in a number of ways in the intervening time, screwing up ordering.
*
* Currently: Take off all armor.
* Picking Locks / Forcing Chests.
*/
void
reset_occupations() {
reset_remarm();
reset_pick();
}
/* If a time is given, use it to timeout this function, otherwise the
* function times out by its own means.
*/
void
set_occupation(fn, txt, xtime)
int NDECL((*fn));
const char *txt;
int xtime;
{
if (xtime) {
occupation = timed_occupation;
timed_occ_fn = fn;
} else
occupation = fn;
occtxt = txt;
occtime = 0;
return;
}
#ifdef REDO
static char NDECL(popch);
/* Provide a means to redo the last command. The flag `in_doagain' is set
* to true while redoing the command. This flag is tested in commands that
* require additional input (like `throw' which requires a thing and a
* direction), and the input prompt is not shown. Also, while in_doagain is
* TRUE, no keystrokes can be saved into the saveq.
*/
#define BSIZE 20
static char pushq[BSIZE], saveq[BSIZE];
static int NEARDATA phead, NEARDATA ptail, NEARDATA shead, NEARDATA stail;
static char
popch() {
/* If occupied, return '\0', letting tgetch know a character should
* be read from the keyboard. If the character read is not the
* ABORT character (as checked in pcmain.c), that character will be
* pushed back on the pushq.
*/
if (occupation) return '\0';
if (in_doagain) return (shead != stail) ? saveq[stail++] : '\0';
else return (phead != ptail) ? pushq[ptail++] : '\0';
}
char
pgetchar() { /* curtesy of aeb@cwi.nl */
register int ch;
if(!(ch = popch()))
ch = nhgetch();
return(ch);
}
/* A ch == 0 resets the pushq */
void
pushch(ch)
char ch;
{
if (!ch)
phead = ptail = 0;
if (phead < BSIZE)
pushq[phead++] = ch;
return;
}
/* A ch == 0 resets the saveq. Only save keystrokes when not
* replaying a previous command.
*/
void
savech(ch)
char ch;
{
if (!in_doagain) {
if (!ch)
phead = ptail = shead = stail = 0;
else if (shead < BSIZE)
saveq[shead++] = ch;
}
return;
}
#endif /* REDO */
#endif /* OVL1 */
#ifdef OVLB
STATIC_PTR int
doextcmd() /* here after # - now read a full-word command */
{
char buf[BUFSZ];
register const struct ext_func_tab *efp = extcmdlist;
again:
#ifdef COM_COMPL
get_ext_cmd(buf);
#else
getlin("#", buf);
#endif
clear_nhwindow(WIN_MESSAGE);
if(buf[0] == '\0' || buf[0] == '\033')
return 0;
if(buf[0] == '?') {
(void) doextlist();
goto again;
}
while(efp->ef_txt) {
if(!strncmpi(efp->ef_txt, buf,BUFSIZ))
return (*(efp->ef_funct))();
efp++;
}
pline("%s: unknown extended command.", buf);
return 0;
}
int
doextlist() /* here after #? - now list all full-word commands */
{
register const struct ext_func_tab *efp;
char buf[BUFSZ];
winid datawin;
datawin = create_nhwindow(NHW_TEXT);
putstr(datawin, 0, "");
putstr(datawin, 0, " Extended Commands List");
putstr(datawin, 0, "");
#ifdef COM_COMPL
putstr(datawin, 0, " Press '#', then type (first letter only):");
#else
putstr(datawin, 0, " Press '#', then type:");
#endif
putstr(datawin, 0, "");
for(efp = extcmdlist; efp->ef_txt; efp++) {
Sprintf(buf, " %-8s - %s.", efp->ef_txt, efp->ef_desc);
putstr(datawin, 0, buf);
}
display_nhwindow(datawin, FALSE);
destroy_nhwindow(datawin);
return 0;
}
#ifdef POLYSELF
STATIC_PTR int
domonability()
{
if (can_breathe(uasmon)) return dobreathe();
else if (attacktype(uasmon, AT_SPIT)) return dospit();
else if (u.usym == S_NYMPH) return doremove();
else if (u.usym == S_UMBER) return doconfuse();
else if (is_were(uasmon)) return dosummon();
else if (webmaker(uasmon)) return dospinweb();
else if (is_hider(uasmon)) return dohide();
else if(u.umonnum == PM_GREMLIN) {
if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
struct monst *mtmp;
if ((mtmp = cloneu()) != 0) {
mtmp->mhpmax = (u.mhmax /= 2);
You("multiply.");
dryup(u.ux,u.uy);
}
} else pline("There is no fountain here.");
}
else if (u.usym == S_UNICORN) {
use_unicorn_horn((struct obj *)0);
return 1;
} else if (u.umonnum == PM_MIND_FLAYER) return domindblast();
else if (uasmon->msound == MS_SHRIEK) {
You("shriek.");
aggravate();
} else if (u.umonnum >= 0)
pline("Any special ability you may have is purely reflexive.");
else You("don't have a special ability!");
return 0;
}
#endif
#ifdef EXPLORE_MODE
STATIC_PTR int
enter_explore_mode()
{
if(!discover && !wizard) {
pline("Beware! From discovery mode there will be no return to normal game.");
if (yn("Do you want to enter discovery mode?") == 'y') {
clear_nhwindow(WIN_MESSAGE);
You("are now in non-scoring discovery mode.");
discover = TRUE;
}
else {
clear_nhwindow(WIN_MESSAGE);
pline("Resuming normal game.");
}
}
return 0;
}
#endif
#ifdef WIZARD
STATIC_PTR int
wiz_wish() /* Unlimited wishes for debug mode by Paul Polderman */
{
if (wizard) {
makewish();
(void) encumber_msg();
} else
pline("Unavailable command '^W'.");
return 0;
}
STATIC_PTR int
wiz_identify()
{
struct obj *obj;
if (!wizard)
pline("Unavailable command '^I'.");
else {
for (obj = invent; obj; obj = obj->nobj)
if (!objects[obj->otyp].oc_name_known || !obj->known
|| !obj->dknown || !obj->bknown)
(void) identify(obj);
}
return 0;
}
STATIC_PTR int
wiz_map()
{
if (wizard) do_mapping();
else pline("Unavailable command '^F'.");
return 0;
}
STATIC_PTR int
wiz_genesis()
{
if (wizard) (void) create_particular();
else pline("Unavailable command '^G'.");
return 0;
}
STATIC_PTR int
wiz_where()
{
if (wizard) print_dungeon();
else pline("Unavailable command '^O'.");
return 0;
}
STATIC_PTR int
wiz_detect()
{
if(wizard) (void) findit();
else pline("Unavailable command '^E'.");
return 0;
}
STATIC_PTR int
wiz_level_tele()
{
if (wizard) level_tele();
else pline("Unavailable command '^V'.");
return 0;
}
#endif /* WIZARD */
/* -enlightenment- */
static winid en_win;
static const char
*You_ = "You ",
*are = "are ", *were = "were ",
*have = "have ", *had = "had ",
*can = "can ", *could = "could ";
#define enl_msg(prefix,present,past,suffix) \
enlght_line(prefix, final ? past : present, suffix)
#define you_are(attr) enl_msg(You_,are,were,attr)
#define you_have(attr) enl_msg(You_,have,had,attr)
#define you_can(attr) enl_msg(You_,can,could,attr)
static void
enlght_line(start, middle, end)
const char *start, *middle, *end;
{
char buf[BUFSZ];
Sprintf(buf, "%s%s%s.", start, middle, end);
putstr(en_win, 0, buf);
}
void
enlightenment(final)
boolean final;
{
int ltmp;
char buf[BUFSZ];
en_win = create_nhwindow(NHW_MENU);
putstr(en_win, 0, final ? "Final Attributes:" : "Current Attributes:");
putstr(en_win, 0, "");
/* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */
if (u.ualign.record >= 20) you_are("piously aligned");
else if (u.ualign.record > 13) you_are("devoutly aligned");
else if (u.ualign.record > 8) you_are("fervently aligned");
else if (u.ualign.record > 3) you_are("stridently aligned");
else if (u.ualign.record == 3) you_are("aligned");
else if (u.ualign.record > 0) you_are("haltingly aligned");
else if (u.ualign.record == 0) you_are("nominally aligned");
else if (u.ualign.record >= -3) you_have("strayed");
else if (u.ualign.record >= -8) you_have("sinned");
else you_have("transgressed");
#ifdef WIZARD
if (wizard) {
Sprintf(buf, " %d", u.ualign.record);
enl_msg("Your alignment ", "is", "was", buf);
}
#endif
if (Telepat) you_are("telepathic");
if (Searching) you_have("automatic searching");
if (Teleportation) you_can("teleport");
if (Teleport_control) you_have("teleport control");
if (See_invisible) enl_msg(You_, "see", "saw", " invisible");
if (Invisible) you_are("invisible");
else if (Invis) you_are("invisible to others");
if (Fast) you_are((Fast & ~INTRINSIC) ? "very fast" : "fast");
if (Stealth) you_are("stealthy");
if (Regeneration) enl_msg("You regenerate", "", "d", "");
if (Hunger) you_have("hunger");
if (Conflict) enl_msg("You cause", "", "d", " conflict");
if (Aggravate_monster) enl_msg("You aggravate", "", "d", " monsters");
if (Poison_resistance) you_are("poison resistant");
if (Fire_resistance) you_are("fire resistant");
if (Cold_resistance) you_are("cold resistant");
if (Shock_resistance) you_are("shock resistant");
if (Sleep_resistance) you_are("sleep resistant");
if (Disint_resistance) you_are("disintegration-resistant");
if (Protection_from_shape_changers)
you_are("protected from shape changers");
#ifdef POLYSELF
if (Polymorph) you_are("polymorphing");
if (Polymorph_control) you_have("polymorph control");
#endif
if (HHalluc_resistance)
enl_msg("You resist", "", "ed", " hallucinations");
if (final) {
if (Hallucination) you_are("hallucinating");
if (Stunned) you_are("stunned");
if (Confusion) you_are("confused");
if (Sick) you_are("sick");
if (Blinded) you_are("blinded");
}
if (Wounded_legs) {
Sprintf(buf, "wounded %s", makeplural(body_part(LEG)));
you_have(buf);
}
if (Glib) {
Sprintf(buf, "slippery %s", makeplural(body_part(FINGER)));
you_have(buf);
}
if (Strangled) you_are("being strangled");
if (Stoned) you_are("turning to stone");
if (Lifesaved)
enl_msg("Your life ", "will be", "would have been", " saved");
if (Adornment) you_are("adorned");
if (Warning) you_are("warned");
if (Protection) you_are("protected");
if (Reflecting) you_have("reflection");
if (Levitation) you_are("levitating");
if (Fumbling) enl_msg("You fumble", "", "d", "");
if (Jumping) you_can("jump");
if (Wwalking) you_can("walk on water");
if (Magical_breathing) you_can("survive without air");
if (Antimagic) you_are("magic-protected");
if (Displaced) you_are("displaced");
if (Clairvoyant) you_are("clairvoyant");
#ifdef POLYSELF
if (u.ulycn != -1) {
Strcpy(buf, an(mons[u.ulycn].mname));
you_are(buf);
}
#endif
if (Luck) {
ltmp = abs((int)Luck);
Sprintf(buf, "%s%slucky",
ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",
Luck < 0 ? "un" : "");
#ifdef WIZARD
if (wizard) Sprintf(eos(buf), " (%d)", Luck);
#endif
you_are(buf);
}
#ifdef WIZARD
else if (wizard) enl_msg("Your luck ", "is", "was", " zero");
#endif
ltmp = stone_luck(TRUE);
if (ltmp > 0) you_have("extra luck");
else if (ltmp < 0) you_have("reduced luck");
if (carrying(LUCKSTONE)) {
ltmp = stone_luck(FALSE);
if (ltmp <= 0)
enl_msg("Bad luck ", "does", "did", " not time out for you");
if (ltmp >= 0)
enl_msg("Good luck ", "does", "did", " not time out for you");
}
display_nhwindow(en_win, TRUE);
destroy_nhwindow(en_win);
return;
}
#if defined(WIZARD) || defined(EXPLORE_MODE)
STATIC_PTR int
wiz_attributes()
{
if (wizard || discover)
enlightenment(FALSE);
else
pline("Unavailable command '^X'.");
return 0;
}
#endif /* WIZARD || EXPLORE_MODE */
#endif /* OVLB */
#ifdef OVL1
#ifndef M
# ifndef NHSTDC
# define M(c) (0x80 | (c))
# else
# define M(c) ((c) - 128)
# endif /* NHSTDC */
#endif
#ifndef C
#define C(c) (0x1f & (c))
#endif
static const struct func_tab cmdlist[] = {
{C('d'), dokick}, /* "D" is for door!...? */
#ifdef WIZARD
{C('e'), wiz_detect},
{C('f'), wiz_map},
{C('g'), wiz_genesis},
{C('i'), wiz_identify},
#endif
{C('l'), doredraw}, /* if number_pad is set */
#ifdef WIZARD
{C('o'), wiz_where},
#endif
{C('p'), doprev_message},
{C('r'), doredraw},
{C('t'), dotele},
#ifdef WIZARD
{C('v'), wiz_level_tele},
{C('w'), wiz_wish},
#endif
#if defined(WIZARD) || defined(EXPLORE_MODE)
{C('x'), wiz_attributes},
#endif
#ifdef SUSPEND
{C('z'), dosuspend},
#endif
{'a', doapply},
{'A', doddoremarm},
{M('a'), doorganize},
/* 'b', 'B' : go sw */
{'c', doclose},
{'C', do_mname},
{M('c'), dotalk},
{'d', dodrop},
{'D', doddrop},
{M('d'), dodip},
{'e', doeat},
{'E', doengrave},
/* Soon to be
{'f', dofight, "fighting"},
{'F', doFight, "fighting"},
*/
{M('f'), doforce},
/* 'g', 'G' : multiple go */
/* 'h', 'H' : go west */
{'h', dohelp}, /* if number_pad is set */
{'i', ddoinv},
{'I', dotypeinv}, /* Robert Viduya */
{M('i'), doinvoke},
/* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
{'j', dojump}, /* if number_pad is on */
{M('j'), dojump},
{'k', dokick}, /* if number_pad is on */
{'l', doloot}, /* if number_pad is on */
{M('l'), doloot},
/* 'n' prefixes a count if number_pad is on */
#ifdef POLYSELF
{M('m'), domonability},
#endif /* POLYSELF */
{'N', ddocall}, /* if number_pad is on */
{M('N'), ddocall},
{'o', doopen},
{'O', doset},
{M('o'), dosacrifice},
{'p', dopay},
{'P', doputon},
{M('p'), dopray},
{'q', dodrink},
{'Q', done2},
{'r', doread},
{'R', doremring},
{M('r'), dorub},
{'s', dosearch, "searching"},
{'S', dosave},
{M('s'), dosit},
{'t', dothrow},
{'T', dotakeoff},
{M('t'), doturn},
/* 'u', 'U' : go ne */
{'u', dountrap}, /* if number_pad is on */
{M('u'), dountrap},
{'v', doversion},
{'V', dohistory},
{M('v'), doextversion},
{'w', dowield},
{'W', dowear},
{M('w'), dowipe},
{'x', dovspell}, /* Mike Stephenson */
#ifdef EXPLORE_MODE
{'X', enter_explore_mode},
#endif
/* 'y', 'Y' : go nw */
{'z', dozap},
{'Z', docast},
{'<', doup},
{'>', dodown},
{'/', dowhatis},
{'&', dowhatdoes},
{'?', dohelp},
#ifdef SHELL
{'!', dosh},
#endif
{'.', donull, "waiting"},
{' ', donull, "waiting"},
{',', dopickup},
{':', dolook},
{';', doquickwhatis},
{'^', doidtrap},
{'\\', dodiscovered}, /* Robert Viduya */
{'@', dotogglepickup},
{WEAPON_SYM, doprwep},
{ARMOR_SYM, doprarm},
{RING_SYM, doprring},
{AMULET_SYM, dopramulet},
{TOOL_SYM, doprtool},
{GOLD_SYM, doprgold},
{SPBOOK_SYM, dovspell}, /* Mike Stephenson */
{'#', doextcmd},
{0,0,0}
};
#undef M
const struct ext_func_tab extcmdlist[] = {
{"adjust", "adjust inventory letters", doorganize},
{"chat", "talk to someone", dotalk}, /* converse? */
{"dip", "dip an object into something", dodip},
{"force", "force a lock", doforce},
{"invoke", "invoke an object's powers", doinvoke},
{"jump", "jump to a location", dojump},
{"loot", "loot a box on the floor", doloot},
#ifdef POLYSELF
{"monster", "use a monster's special ability", domonability},
#endif
{"name", "name an item or type of object", ddocall},
{"offer", "offer a sacrifice to the gods", dosacrifice},
{"pray", "pray to the gods for help", dopray},
{"rub", "rub a lamp", dorub},
{"sit", "sit down", dosit},
{"turn", "turn undead", doturn},
{"untrap", "untrap something", dountrap},
{"version", "list compile time options for this version of NetHack",
doextversion},
#ifdef MAC
{"window", "clean up windows", SanePositions},
#endif
{"wipe", "wipe off your face", dowipe},
{"?", "get this list of extended commands", doextlist},
{NULL, NULL, donull}
};
#define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
#define unmeta(c) (0x7f & (c))
void
rhack(cmd)
register char *cmd;
{
register const struct func_tab *tlist = cmdlist;
boolean firsttime = FALSE;
register int res;
if(!cmd) {
firsttime = TRUE;
flags.nopick = 0;
cmd = parse();
}
if(*cmd == (char)033) {
flags.move = 0;
return;
}
#ifdef REDO
if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
in_doagain = TRUE;
stail = 0;
rhack(NULL); /* read and execute command */
in_doagain = FALSE;
return;
}
/* Special case of *cmd == ' ' handled better below */
if(!*cmd || *cmd == (char)0377) {
#else
if(!*cmd || *cmd == (char)0377 ||
(!flags.rest_on_space && *cmd == ' ')) {
#endif
nhbell();
flags.move = 0;
return; /* probably we just had an interrupt */
}
if(movecmd(*cmd)) {
walk:
if(multi) flags.mv = 1;
domove();
return;
}
if(movecmd(flags.num_pad ? unmeta(*cmd) : lowc(*cmd))) {
flags.run = 1;
rush:
if(firsttime){
if(!multi) multi = COLNO;
u.last_str_turn = 0;
}
flags.mv = 1;
domove();
return;
}
if(*cmd == 'g' && movecmd(cmd[1])) {
flags.run = 2;
goto rush;
}
if (((*cmd == 'G' || (flags.num_pad && *cmd == '5')) &&
movecmd(lowc(cmd[1]))) || movecmd(unctrl(*cmd))) {
flags.run = 3;
goto rush;
}
if((*cmd == 'm' || (flags.num_pad && *cmd == '-')) &&
movecmd(cmd[1])) {
flags.run = 0;
flags.nopick = 1;
goto walk;
}
if(*cmd == 'M' && movecmd(lowc(cmd[1]))) {
flags.run = 1;
flags.nopick = 1;
goto rush;
}
if (flags.num_pad && *cmd == '0') {
(void)ddoinv(); /* A convenience borrowed from the PC */
flags.move = 0;
multi = 0;
return;
}
while(tlist->f_char) {
if((*cmd & 0xff) == (tlist->f_char & 0xff)){
/* Special case of *cmd == ' ' handled here */
if (*cmd == ' ' && !flags.rest_on_space)
break;
/* Now control-A can stop lengthy commands */
/* in the PC version only -- use ^C-N otherwise */
if (tlist->f_text && !occupation && multi)
#ifdef GCC_WARN
set_occupation(tlist->f_funct,
tlist->f_text, multi);
#else
set_occupation(((struct func_tab *)tlist)->f_funct,
tlist->f_text, multi);
#endif
res = (*(tlist->f_funct))();
if(!res) {
flags.move = 0;
multi = 0;
}
return;
}
tlist++;
}
{ char expcmd[10];
register char *cp = expcmd;
while(*cmd && cp-expcmd < sizeof(expcmd)-2) {
if(*cmd >= 040 && *cmd < 0177)
*cp++ = *cmd++;
else if (*cmd & 0200) {
*cp++ = 'M';
*cp++ = '-';
*cp++ = *cmd++ &=~ 0200;
}
else {
*cp++ = '^';
*cp++ = *cmd++ ^ 0100;
}
}
*cp = 0;
Norep("Unknown command '%s'.", expcmd);
}
multi = flags.move = 0;
return;
}
int
xytod(x, y) /* convert an x,y pair into a direction code */
schar x, y;
{
register int dd;
for(dd = 0; dd < 8; dd++)
if(x == xdir[dd] && y == ydir[dd]) return dd;
return -1;
}
#ifdef WALKIES
void
dtoxy(cc,dd) /* convert a direction code into an x,y pair */
coord *cc;
register int dd;
{
cc->x = xdir[dd];
cc->y = ydir[dd];
return;
}
#endif /* WALKIES */
int
movecmd(sym) /* also sets u.dz, but returns false for <> */
char sym;
{
register const char *dp;
register const char *sdp = flags.num_pad ? ndir : sdir;
u.dz = 0;
if(!(dp = index(sdp, sym))) return 0;
u.dx = xdir[dp-sdp];
u.dy = ydir[dp-sdp];
u.dz = zdir[dp-sdp];
#ifdef POLYSELF
if (u.dx && u.dy && u.umonnum == PM_GRID_BUG) {
u.dx = u.dy = 0;
return 0;
}
#endif
return !u.dz;
}
int
getdir(s)
const char *s;
{
char dirsym;
#ifdef REDO
if(in_doagain)
dirsym = readchar();
else
#endif
dirsym = yn_function (s ? s : "In what direction?", NULL, '\0');
#ifdef REDO
savech(dirsym);
#endif
if(dirsym == '.' || dirsym == 's')
u.dx = u.dy = u.dz = 0;
else if(!movecmd(dirsym) && !u.dz) {
if(!index(quitchars, dirsym))
pline("What a strange direction!");
return 0;
}
if(!u.dz && (Stunned || (Confusion && !rn2(5)))) confdir();
return 1;
}
#endif /* OVL1 */
#ifdef OVLB
void
confdir()
{
register int x =
#ifdef POLYSELF
(u.umonnum == PM_GRID_BUG) ? 2*rn2(4) :
#endif
rn2(8);
u.dx = xdir[x];
u.dy = ydir[x];
return;
}
#endif /* OVLB */
#ifdef OVL0
int
isok(x,y)
register int x, y;
{
/* x corresponds to curx, so x==1 is the first column. Ach. %% */
return x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1;
}
static int NEARDATA last_multi;
/*
* convert a MAP window position into a movecmd
*/
static int
click_to_cmd(x, y, mod)
int x, y, mod;
{
x -= u.ux;
y -= u.uy;
/* convert without using floating point, allowing sloppy clicking */
if(x > 2*abs(y))
x = 1, y = 0;
else if(y > 2*abs(x))
x = 0, y = 1;
else if(x < -2*abs(y))
x = -1, y = 0;
else if(y < -2*abs(x))
x = 0, y = -1;
else
x = sgn(x), y = sgn(y);
if(x == 0 && y == 0) /* map click on player to "rest" command */
return '.';
x = xytod(x, y);
if(mod == CLICK_1) {
return (flags.num_pad ? ndir[x] : sdir[x]);
} else {
return (sdir[x] - 'a' + 'A'); /* run command */
}
}
STATIC_OVL char *
parse()
{
#ifdef LINT /* static char in_line[COLNO]; */
char in_line[COLNO];
#else
static char in_line[COLNO];
#endif
register int foo;
boolean prezero = FALSE;
multi = 0;
flags.move = 1;
flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
if (!flags.num_pad || (foo = readchar()) == 'n')
for (;;) {
foo = readchar();
if (foo >= '0' && foo <= '9') {
multi = 10 * multi + foo - '0';
if (multi < 0 || multi > LARGEST_INT) multi = LARGEST_INT;
if (multi > 9) {
clear_nhwindow(WIN_MESSAGE);
Sprintf(in_line, "Count: %d", multi);
pline(in_line);
mark_synch();
}
last_multi = multi;
if (!multi && foo == '0') prezero = TRUE;
} else break; /* not a digit */
}
if (foo == '\033') { /* esc cancels count (TH) */
clear_nhwindow(WIN_MESSAGE);
multi = last_multi = 0;
# ifdef REDO
} else if (foo == DOAGAIN || in_doagain) {
multi = last_multi;
} else {
last_multi = multi;
savech(0); /* reset input queue */
savech((char)foo);
# endif
}
if (multi) {
multi--;
save_cm = in_line;
} else {
save_cm = NULL;
}
in_line[0] = foo;
in_line[1] = '\0';
if (foo == 'g' || foo == 'G' || (flags.num_pad && foo == '5') ||
foo == 'm' || foo == 'M') {
foo = readchar();
#ifdef REDO
savech((char)foo);
#endif
in_line[1] = foo;
in_line[2] = 0;
}
clear_nhwindow(WIN_MESSAGE);
if (prezero) in_line[0] = '\033';
return(in_line);
}
#endif /* OVL0 */
#ifdef OVLB
#ifdef UNIX
static
void
end_of_input()
{
exit_nhwindows("End of input?");
#ifndef NOSAVEONHANGUP
if(!hu) {
hu = TRUE;
(void) dosave0();
}
#endif
clearlocks();
terminate(0);
}
#endif
#endif /* OVLB */
#ifdef OVL0
char
readchar()
{
register int sym;
int x, y, mod;
#ifdef REDO
sym = in_doagain ? Getchar() : nh_poskey(&x, &y, &mod);
#else
sym = Getchar();
#endif
#ifdef UNIX
# ifdef NR_OF_EOFS
if (sym == EOF) {
register int cnt = NR_OF_EOFS;
/*
* Some SYSV systems seem to return EOFs for various reasons
* (?like when one hits break or for interrupted systemcalls?),
* and we must see several before we quit.
*/
do {
clearerr(stdin); /* omit if clearerr is undefined */
sym = Getchar();
} while (--cnt && sym == EOF);
}
# endif /* NR_OF_EOFS */
if (sym == EOF)
end_of_input();
#endif /* UNIX */
if(sym == 0) /* click event */
sym = click_to_cmd(x, y, mod);
return((char) sym);
}
#endif /* OVL0 */
/*cmd.c*/